#!/usr/bin/python
"""Adaptor to download a full game CSV from BGG and upload it to choosegame

The adaptor is responsible for splitting the input up into nice chunks.
"""

import getopt
import httplib
import re
import sys
import urllib

# Access URLs for the live and development versions of the server.
dev_url = "localhost:8080"
live_url = "choosegame.appspot.com"

def ReadSecret(secretfile):
  "Very naive method to grab a secret from a file that contains only that"
  sf = open(secretfile, "r")
  return sf.read().strip()

def FetchData(user, savefile=None):
  """Fetches a User collection from BGG

  Args:
    user       the BGG username to fetch
    savefile   an optional filename to save the downloaded CSV in.

  Returns:
    a iterable over the CSV lines with newlines included
  """

  params = urllib.urlencode({ "action": "exportcsv",
                              "subtype": "boardgame",
                              "username": user })
  url = "http://www.boardgamegeek.com/geekcollection.php?" + params
  openurl = urllib.urlopen(url)
  content_type = openurl.info().gettype()
  data = openurl.read()

  if savefile:
    cachefile = open(savefile, "w")
    cachefile.write(data)
    cachefile.close()

  

  print "Received data as", content_type
  if content_type != "text/comma-separated-values":
    print "Receive non-csv data page. Ignoring"
    data = ""

  return data
  #data =  map(lambda x: x + "\n", filter(lambda x: x, data.split("\n")))
  #return iter(data)

def ClearData(http_conn, user):
  # TODO. check return values.
  http_conn.request("GET", "/data/clearuser?bgguser=%s" % user)
  response = http_conn.getresponse()

def UploadData(instance, user, data_iter):
  headers = data_iter.next()

  conn = httplib.HTTPConnection(instance)

  # have this negotiate start/end of upload.
  ClearData(conn, user)
  conn.close()

  data = ""
  count = 0

  chunksize = 50
  for line in data_iter:
    data += line
    count = count + 1
    if count >= chunksize and re.search(r"\"$", line):
      # check for errors here.
      SingleUpload(instance, user, headers + data)
      count = 0
      data = ""

  if count > 0:
    SingleUpload(instance, user, headers + data)

def SingleUpload(instance, user, data, chunk=False, secret=""):
  if chunk:
    print "uploading %d bytes" % len(data)
  else:
    print "uploading"
  http_conn = httplib.HTTPConnection(instance)
  params = urllib.urlencode({'bgguser': user, 'data':data, 'token':secret})
  headers = {"Content=type": "application/x-www-form-urlencoded",
             "Accept": "text/plain" }

  if chunk:
    url_path = "/data/storechunkcsv"
  else:
    url_path = "/data/storegamescsv"

  http_conn.request("POST", url_path, params, headers)
  response = http_conn.getresponse()
  print response.status, response.reason, "from", instance, url_path
  data = response.read()
  print data

  http_conn.close()
  return response.status >= 200 and response.status <= 300

def Usage():
  print "Usage: upload_games [ OPTIONS ] bgguser"
  print "options:"
  print "  --chunk            Use new chunk interface"
  print "  --dev              Use local development instance"
  print "  --data=file.csv    File of cached csv data"
  print "  --quiet            Only print errors"   # unimplemented.
  print "  --save             Download + save to csv data file"
  print "  --secret           File containing the upload secret"


def main(argv):
  try:
    (opts, argv) = getopt.getopt(argv, "", [ "chunk", "dev", "data=", "save" ,
                                             "secret"])
  except getopt.GetoptError:
    Usage()
    sys.exit(2)

  opts = dict(opts)
  if "--dev" in opts:
    instance = dev_url
  else:
    instance = live_url

  if len(argv) != 1:
    Usage()
    sys.exit(2)

  user = argv[0].strip().lower()

  if "--data" in opts and not "--save" in opts:
    csv_filename = opts["--data"]
    csv_data = open(csv_filename, "r").read()
  else:
    if "--save" in opts and not "--data" in opts:
       print "You must specify --data with --save"
       Usage()
       sys.exit(2)
    if "--save" in opts:
      csv_data = FetchData(user, savefile=opts["--data"])
    else:
      csv_data = FetchData(user)

  if "--secret" in opts:
    secretfile = opts["--secret"]
  else:
    secretfile = "../data/secret"

  secret = ReadSecret(secretfile)

  print "Attempting to upload data for", user
  if "--chunk" in opts:
    SingleUpload(instance, user, csv_data, chunk=True, secret=secret)
  else:
    print "Piecewise upload not currently working"
    sys.exit(1)
    UploadData(instance, user, csv_data)

if __name__ == "__main__":
  main(sys.argv[1:])
